/**
 * 
 */
package be.gwi.alfresco.run.js.impl;

import java.util.Date;

import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;

import be.gwi.alfresco.run.exception.ServiceException;
import be.gwi.alfresco.run.model.Run;
import be.gwi.alfresco.run.model.RunType;
import be.gwi.alfresco.run.model.Runner;
import be.gwi.alfresco.run.service.RunnerService;

/**
 * 
 * @author gabriel.wilems@gmail.com
 * @see JSRunnerService
 * 
 * @version 1.0
 * @since 1.0
 */
public class JSRunnerServiceImpl extends BaseScopableProcessorExtension {
    private static Log    logger = LogFactory.getLog(JSRunnerServiceImpl.class);

    private RunnerService runnerService;

    /**
     * Initializes the service.
     * 
     * Verifies that all the attributes have been set.
     * 
     * @throws IllegalArgumentException
     *             if not all attributes have been set.
     */
    public void init() {
        Assert.notNull(this.runnerService, "The runner facade must have been set");
    }

    /**
     * Get a runner bean from the given username
     * 
     * @param username
     * @return
     */
    public Runner getRunner(String username) {
        try {
            return this.runnerService.getRunner(username);
        } catch (ServiceException e) {
            logger.error("Fail to get runner " + username + ": " + e.getMessage(), e);
            return null;
        }
    }

    /**
     * Get a runner bean from the current user
     * 
     * @return
     */
    public Runner getCurrentRunner() throws ServiceException {
        try {
            return this.runnerService.getCurrentRunner();
        } catch (ServiceException e) {
            logger.error("Fail to get current runner: " + e.getMessage(), e);
            return null;
        }
    }

    /**
     * Add Run to current Runner
     * 
     * @param run
     */
    public void addRun(Date runDate, Double runDistance, String runType, String runUrl) {
        // TODO test input is valid
        Run run = new Run(runDate, runDistance, RunType.getRunType(runType), runUrl);
        try {
            this.runnerService.addRun(run);
        } catch (ServiceException e) {
            logger.error("Fail to add run to current runner: " + e.getMessage(), e);
        }
    }

    /**
     * Get a runner history from the given username
     * 
     * @param username
     * @param year
     * @return
     */
    public Object[] getHistory(String username, String year) {
        try {
            return this.runnerService.getHistory(username, year).toArray();
        } catch (ServiceException e) {
            logger.error("Fail to get history for runner " + username + ": " + e.getMessage(), e);
            return null;
        }
    }

    /**
     * Get a current runner history
     * 
     * @param year
     * @return
     */
    public Object[] getCurrentHistory(String year) {
        try {
            return this.runnerService.getCurrentHistory(year).toArray();
        } catch (ServiceException e) {
            logger.error("Fail to get current history: " + e.getMessage(), e);
            return null;
        }
    }

    /**
     * Get a runner history from the given username by run type
     * 
     * @param username
     * @param runType
     * @return
     */
    public Object[] getHistoryByRunType(String username, String runType) {
        try {
            return this.runnerService.getHistoryByRunType(username, RunType.getRunType(runType)).toArray();
        } catch (ServiceException e) {
            logger.error("Fail to get history for runner " + username + ": " + e.getMessage(), e);
            return null;
        }
    }

    /**
     * Get a current runner history by runType
     * 
     * @param runType
     * @return
     */
    public Object[] getCurrentHistoryByRunType(String runType) {
        try {
            return this.runnerService.getCurrentHistoryByRunType(RunType.getRunType(runType)).toArray();
        } catch (ServiceException e) {
            logger.error("Fail to get current history: " + e.getMessage(), e);
            return null;
        }
    }

    /**
     * Get ranking for the given runType
     * 
     * @param runTypeString
     * @return
     */
    public Object[] getRanking(String runTypeString) {
        RunType runType = RunType.getRunType(runTypeString);
        try {
            return this.runnerService.getRanking(runType).toArray();
        } catch (ServiceException e) {
            logger.error("Fail to get current ranking: " + e.getMessage(), e);
            return null;
        }
    }

    /**
     * @param runnerService
     *            the runnerService to set
     */
    public void setRunnerService(RunnerService runnerService) {
        this.runnerService = runnerService;
    }
}
